<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of BPermit
 *
 * @author I062261
 */
class BPermit extends BGroup {

    const AllowAccess = 'allowAccess';
    const Not_AllowAccess = 'not_allowAccess';
    const Role_Not_Allow_Join = 'not_allow_join_role';
    const Role_Allow_Join = 'allow_join_role';
    const Role_Allow_Auto_Join = 'allow_auto_join_role';
    const Role_Not_Auto_Join = 'not_auto_join_role';
    const AllowModify = 'allow_modify';

    public $name = null;
    public $description = null;
    public $spaceId = null;
    public $appId = null;
    public $data = null;

    public static function checkUserPermit($resource, $access = null, $user = NULL, $data = NULL) {

        //by default, set permit as allowAccess
        $permit = self::find(self::AllowAccess);

        if (is_numeric($access))
            $permit = new BPermit($access);

        if (is_string($access))
            $permit = self::find($access);

        if (!$permit instanceof BPermit)
            return FALSE;

        $context = array('spaceId' => Blyn::app()->getActiveSpace()->getId(), 'appId' => Blyn::app()->getActiveApp()->getId());

        $userRoles = BRole::findUserRoles($user, $context, TRUE);

        foreach ($userRoles as $role) {
            $pairEntities = BPairEntity::buildPairEntity($resource, array(new BPermit(), $role));
            $permitObjList = $pairEntities->getPairObjList();
            $userList = $pairEntities->getUserList();
            //$rEntitis = BRelationshipEntity::findAll(array('mainObj' => $resource, 'pairObjs' => array(new BPermit(), $role)));
            foreach ($permitObjList as $permitId => $permitObj) {
                //$permitObj = $rEntity->pairObjs[0];                
                if ($permitObj->isChildOf($permit) || $permitObj->getId() == $permit->getId())
                    if (isset($userList[$permitId]) && $userList[$permitId] != NULL) {
                        //if set user for permit, further check userId
                        $user = $userList[$permitId];
                        if ($user instanceof BUser) {
                            if (Blyn::app()->getCurrentUser()->getId() == $user->getId())
                                return TRUE;
                        }
                    }
                    else
                        return TRUE;
            }
        }

        return FALSE;
    }
    
    public static function checkUserRoleParentPermit($resource, $access = null, $user = NULL, $data = NULL) {

        //by default, set permit as allowAccess
        $permit = self::find(self::AllowAccess);

        if (is_numeric($access))
            $permit = new BPermit($access);

        if (is_string($access))
            $permit = self::find($access);

        if (!$permit instanceof BPermit)
            return FALSE;

        $context = array('spaceId' => Blyn::app()->getActiveSpace()->getId(), 'appId' => Blyn::app()->getActiveApp()->getId());

        $userRoles = BRole::findUserRoles($user, $context, TRUE);

        foreach ($userRoles as $role) {
            $parentRole = new BRole($role->parentId);
            $pairEntities = BPairEntity::buildPairEntity($resource, array(new BPermit(), $parentRole));
            $permitObjList = $pairEntities->getPairObjList();
            $userList = $pairEntities->getUserList();
            //$rEntitis = BRelationshipEntity::findAll(array('mainObj' => $resource, 'pairObjs' => array(new BPermit(), $role)));
            foreach ($permitObjList as $permitId => $permitObj) {
                //$permitObj = $rEntity->pairObjs[0];                
                if ($permitObj->isChildOf($permit) || $permitObj->getId() == $permit->getId())
                    if (isset($userList[$permitId]) && $userList[$permitId] != NULL) {
                        //if set user for permit, further check userId
                        $user = $userList[$permitId];
                        if ($user instanceof BUser) {
                            if (Blyn::app()->getCurrentUser()->getId() == $user->getId())
                                return TRUE;
                        }
                    }
                    else
                        return TRUE;
            }
        }

        return FALSE;
    }

    public static function checkResourcePermit($resource, $permit = null, $roles = array(), $data = NULL) {
        //by default, set permit as allowAccess
        $oPermit = self::find(self::AllowAccess);
        //$oRoles = array();

        if (is_numeric($permit))
            $oPermit = new BPermit($permit);

        if (is_string($permit))
            $oPermit = self::find($permit);

        if ($permit instanceof BPermit)
            $oPermit = $permit;

        if (!$oPermit instanceof BPermit)
            return FALSE;

        if (is_string($roles)) {
            $role = BRole::find($roles);
            $roles = array();
            $roles[$role->getId()] = $role;
        }

        if ($roles instanceof BRole) {
            $role = $roles;
            $roles = array();
            $roles[$role->getId()] = $role;
        }

        if (is_array($roles) && $roles == NULL) {
            $allRole = BRole::find(BRole::All_Roles);
            $roles[$allRole->getId()] = $allRole;
        }

        if (!$resource instanceof BEntity)
            return FALSE;

        foreach ($roles as $role) {
            $pairEntities = BPairEntity::buildPairEntity($resource, array(new BPermit(), $role));
            if (!$pairEntities instanceof BPairEntity)
                return FALSE;
            $permtObjList = $pairEntities->getPairObjList();
            $userList = $pairEntities->getUserList();
            //$rEntitis = BRelationshipEntity::findAll(array('mainObj' => $resource, 'pairObjs' => array(new BPermit(), $role)));
            foreach ($permtObjList as $permitId => $permitObj) {
                //$permitObj = $rEntity->pairObjs[0];                
                if ($permitObj->isChildOf($permit) || $permitObj->getId() == $oPermit->getId()) {
                    if (isset($userList[$permitId]) && $userList[$permitId] != NULL) {
                        //if set user for permit, further check userId
                        $user = $userList[$permitId];
                        if ($user instanceof BUser) {
                            if (Blyn::app()->getCurrentUser()->getId() == $user->getId())
                                return TRUE;
                        }
                    }
                    else
                        return TRUE;
                }
            }
        }
        return FALSE;
    }

    /**
     * 
     * @param BEntity $resource
     * @param type $permit
     * @param type $role
     * @param type $data
     */
    public static function addPermit($resource, $permit, $roles, $data = NULL) {

        $app = NULL;

        if (!$resource instanceof BEntity)
            return FALSE;

        if ($data instanceof BApp)
            $app = $data;

        $permit = BPermit::find($permit);

        if (!$permit instanceof BPermit)
            return FALSE;

        $roles = BRole::parseRolesIntoObjectList($roles, $app);

        if ($roles != NULL) {
            foreach ($roles as $role) {
                //$obj = new BRelationshipEntity($resource, array($permit, $role));
                $obj = BPairEntity::buildPairEntity($resource, array($permit, $role));
                $obj->resourceClass = get_class($resource);
                if (is_array($data) && isset($data['userId']) && is_numeric($data['userId']) && $data['userId'] > 0)
                    $obj->userId = $data['userId'];
                if (is_array($data) && isset($data['circleId']) && is_numeric($data['userId']) && $data['circleId'] > 0)
                    $obj->circleId = $data['circleId'];
                $obj->save();
            }
        }
    }

    //add predefined permit
    private static function init() {

        $count = BRepositoryFactory::createRepository()->getCount(new BPermit());

        if ($count == 1) {
            $permit = new BPermit();
            $permit->name = self::AllowAccess;
            $permit->save();
            $root = self::getRoot();
            $root->addChildItem($permit);
            $allowJoinPermit = new BPermit();
            $allowJoinPermit->name = self::Role_Allow_Join;
            $allowJoinPermit->save();
            $root->addChildItem($allowJoinPermit);
            $permit = new BPermit();
            $permit->name = self::Role_Allow_Auto_Join;
            $permit->save();
            $allowJoinPermit->addChildItem($permit);
            $permit = new BPermit();
            $permit->name = self::Not_AllowAccess;
            $permit->save();
            $root->addChildItem($permit);
            $notpermit = new BPermit();
            $notpermit->name = self::Role_Not_Allow_Join;
            $notpermit->save();
            $permit->addChildItem($notpermit);
            $notAutoPermit = new BPermit();
            $notAutoPermit->name = self::Role_Not_Auto_Join;
            $notAutoPermit->save();
            $notpermit->addChildItem($notAutoPermit);
            $allowModify = new BPermit();
            $allowModify->name = self::AllowModify;
            $allowModify->save();
            $root->addChild($allowModify);
        }
    }

    public static function find($context) {
        self::init();
        return parent::find($context);
    }

}

?>
